#include <fcitx/keys.h>
#include <fcitx/candidate.h>
/***************************************************************************
 *   Copyright (C) 2017      by hebinq                                     *
 *   hebinq@qq.com                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
 ***************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcitx/ime.h>
#include <fcitx-config/fcitx-config.h>
#include <fcitx-config/xdg.h>
#include <fcitx-utils/log.h>
#include <fcitx-utils/utils.h>
#include <fcitx-utils/utf8.h>
#include <fcitx/instance.h>
#include <fcitx/context.h>
#include <fcitx/module.h>
#include <fcitx/hook.h>
#include <libintl.h>
#include <iconv.h>

#include "config.h"
#include "shuoxie-internal.h"

 

static void *FcitxShuoXieCreate(FcitxInstance *instance);
static void FcitxShuoXieDestroy(void *arg);
static void FcitxShuoXieReloadConfig(void *arg);
CONFIG_DEFINE_LOAD_AND_SAVE(ShuoXie, FcitxShuoXieConfig, "fcitx-shuoxie")
DECLARE_ADDFUNCTIONS(ShuoXie)

FCITX_DEFINE_PLUGIN(fcitx_spell, module, FcitxModule) = {
    .Create = FcitxShuoXieCreate,
    .Destroy = FcitxShuoXieDestroy,
    .SetFD = NULL,
    .ProcessEvent = NULL,
    .ReloadConfig = FcitxShuoXieReloadConfig
};


static void*
FcitxShuoXieCreate(FcitxInstance *instance)
{
printf("FcitxShuoXieCreate\n");
    FcitxShuoXie *shuoxie = fcitx_utils_new(FcitxShuoXie);
    bindtextdomain("fcitx-shuoxie", LOCALEDIR);
    shuoxie->owner = instance;

    if (!ShuoXieLoadConfig(&shuoxie->config)) {
        free(shuoxie);
        return NULL;
    }

    FcitxShuoXieAddFunctions(instance);
    return shuoxie;
}

static void
FcitxShuoXieDestroy(void *arg)
{
printf("FcitxShuoXieDestroy\n");
    FcitxShuoXie *shuoxie = (FcitxShuoXie*)arg;
    free(shuoxie);
}

static void
FcitxShuoXieReloadConfig(void *arg)
{
printf("FcitxShuoXieReloadConfig\n");
    FcitxShuoXie *shuoxie = (FcitxShuoXie*)arg;
    ShuoXieLoadConfig(&shuoxie->config);
}

#include "fcitx-shuoxie-addfunctions.h"
#include <dbus/dbus.h>
#include <fcitx/module/dbus/dbusstuff.h>

typedef struct _FcitxSXState {
    char     strSXHZ[2];
    char     strSXHZUTF8[UTF8_MAX_LENGTH + 1];    
    FcitxInstance *owner;
    DBusConnection* conn;
} FcitxSXState;

static void* SXCreate(struct _FcitxInstance* instance);
INPUT_RETURN_VALUE DoSXInput(void* arg, FcitxKeySym sym, unsigned int state);
INPUT_RETURN_VALUE SXGetCandWords(void *arg);
INPUT_RETURN_VALUE SXGetCandWord(void *arg, FcitxCandidateWord* candWord);
boolean SXInit(void *arg);
void SXDestroy(void *arg);
DBusHandlerResult ShuoXieDBusFilter ( DBusConnection* connection, DBusMessage* msg, void* user_data );

FCITX_DEFINE_PLUGIN(fcitx_shuoxie, ime, FcitxIMClass) = {
    SXCreate,
    SXDestroy
};


void* SXCreate(struct _FcitxInstance* instance)
{

    FcitxSXState* hwstate = fcitx_utils_malloc0(sizeof(FcitxSXState));
    FcitxInstanceRegisterIM(
        instance,
        hwstate,
        "shuoxie",
        _("ShuoXie"),
        "shuoxie",
        SXInit,
        NULL,
        DoSXInput,
        SXGetCandWords,
        NULL,
        NULL,
        NULL,
        NULL,
        100 /* make shuoxie place at last */,
        "zh_CN"
    );
    hwstate->owner = instance;
    printf("shuoxie create \n");
    
    
    FcitxModuleFunctionArg arg;
	
	hwstate->conn = InvokeFunction ( instance, FCITX_DBUS, GETCONNECTION, arg );

	if (hwstate->conn == NULL)
	{
		free ( hwstate );
		return NULL;
	}

	DBusError err;
	dbus_error_init ( &err );
	dbus_bus_add_match ( hwstate->conn,
	                     "type='signal',interface='org.fcitx.ShuoXie'",
	                     &err );

	dbus_connection_flush ( hwstate->conn );
	if ( dbus_error_is_set ( &err ) )
	{
		dbus_error_free ( &err );
		FcitxLog ( ERROR, "Match Error (%s)", err.message );
		free ( hwstate );
		return NULL;
	}

	if ( !dbus_connection_add_filter ( hwstate->conn, ShuoXieDBusFilter, hwstate, NULL ) )
	{
		FcitxLog ( ERROR, "No memory" );
		free ( hwstate );
		return NULL;
	}
	
    
    return hwstate;
}

boolean SXInit(void *arg)
{
    FcitxSXState* hwstate = (FcitxSXState*) arg;    
    FcitxInstanceSetContext(hwstate->owner, CONTEXT_IM_KEYBOARD_LAYOUT, "us");
    printf("shuoxie init \n"); 
    
     DBusMessage *msg = dbus_message_new_method_call (
	                       "org.fcitx.ShuoXie",
	                       "/handwriting",
	                       "org.fcitx.ShuoXie",
	                       "startup"
	                   );

	dbus_connection_send ( hwstate->conn, msg, NULL );
	dbus_message_unref ( msg );


    
    return true;
}

void
SXDestroy(void *arg)
{
    printf("hwDestroy\n");
    FcitxSXState *shuoxie = (FcitxSXState*)arg;
    free(shuoxie);
}
/*************************************************
 * 输入预处理，接收那个键的输入
 * 
 * ***********************************************/

INPUT_RETURN_VALUE DoSXInput(void* arg, FcitxKeySym sym, unsigned int state)
{
    return IRV_TO_PROCESS;
 
}
INPUT_RETURN_VALUE SXGetCandWord(void *arg, FcitxCandidateWord* candWord)
{
    FcitxSXState* hwstate = (FcitxSXState*) arg;
    FcitxInputState* input = FcitxInstanceGetInputState(hwstate->owner);

    strcpy(FcitxInputStateGetOutputString(input),
           candWord->strWord);
    return IRV_COMMIT_STRING;
}


INPUT_RETURN_VALUE SXGetCandWords(void *arg)
{
    printf("shuoxie getcandwords \n");
    
    return IRV_DISPLAY_CANDWORDS;
}

DBusHandlerResult ShuoXieDBusFilter ( DBusConnection* connection, DBusMessage* msg, void* user_data )
{
    
	char* s0 = NULL;
	DBusError error;
	FcitxSXState* shuoxie = ( FcitxSXState* ) user_data;
	dbus_error_init ( &error );
	if ( dbus_message_is_signal ( msg, "org.fcitx.ShuoXie", "send_word" ) )
	{
		if ( dbus_message_get_args ( msg, &error, DBUS_TYPE_STRING, &s0 ,DBUS_TYPE_INVALID ) )
		{
            
			FcitxInstanceCommitString(shuoxie->owner,
                              FcitxInstanceGetCurrentIC(shuoxie->owner), s0);
            printf("发送信息：%s\n",s0);
			//CommitString ( shuoxie->owner, GetCurrentIC ( shuoxie->owner ), s0 );		
            
        }
		return DBUS_HANDLER_RESULT_HANDLED;
	}
	dbus_error_free ( &error );
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
